#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <mqueue.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define MAX_MSG_SIZE 100

int main(int argc, char const *argv[])
{
    char *mq_name = "/my_queue1";

    struct mq_attr attr;  
    attr.mq_flags = 0;  
    attr.mq_maxmsg = 10;  
    attr.mq_msgsize = 100;  
    attr.mq_curmsgs = 0; 
    mqd_t mq_id = mq_open(mq_name, O_CREAT | O_RDWR, 0666, &attr);
    if (mq_id == -1)
    {
        perror("mq_open");
        exit(EXIT_FAILURE);
    }



    pid_t pid = fork();
    if (pid == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else if (pid == 0)
    {
        // 子进程进行读数据
        char recv_buf[MAX_MSG_SIZE];
        struct timespec ts;
        for (int i = 0; i < 10; i++)
        {   
            memset(recv_buf,0,100);
            clock_gettime(0, &ts);
            ts.tv_sec += 15;
            ssize_t recv_len = mq_timedreceive(mq_id, recv_buf, MAX_MSG_SIZE, NULL, &ts);
            if (recv_len == -1)
            {
                perror("mq_timedreceive");
                if (errno == ETIMEDOUT)
                {
                    printf("子进程接收超时\n");
                }
                else
                {
                    printf("子进程接收错误\n");
                }
            }else
            {
                printf("子进程接收数据成功: %s\n", recv_buf);
            }
        }
    }
    else
    {
        // 父进程进行写数据
        char send_buf[MAX_MSG_SIZE];
        struct timespec ts;
        for (int i = 0; i < 10; i++)
        {
            memset(send_buf, 0, MAX_MSG_SIZE);
            clock_gettime(0, &ts);
            ts.tv_sec += 5; // 增加发送时间，确保子进程有足够时间接收
            sprintf(send_buf, "父进程第%d次发送数据", i+1);
            if (mq_timedsend(mq_id, send_buf, strlen(send_buf), 0, &ts) == -1)
            {
                perror("mq_timedsend");
                printf("父进程发送错误\n");
            }
            else
            {
                printf("父进程发送数据成功\n");
            }
            sleep(1);
        }
    }

    close(mq_id);

    if (pid == 0)
    {
        mq_unlink(mq_name);
    }

    return 0;
}
